package somar_test_hello.parser.rselV1_4a;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Vector;

import org.xml.sax.ext.Attributes2Impl;

import somar.RSELRepository;

public class ListVisitor extends Visitor{
	
	private String composedServiceName;
	
	public static int count = 0;
	
	public String getComposedSerivceName() {
		return this.composedServiceName;
	}
	
	public void visit(ProcessElement node){
		printElement(node);
	}

	public void visit(ClasslibElement node){
		printElement(node);
	}

	public void visit(ClassElement node){
		printElement(node);
	}

	public void visit(VariableElement node){
		printElement(node);
	}

	public void visit(RSELElement node){
		Attributes2Impl attr = node.getAttribues();
		for(int i=0; i<attr.getLength(); i++) {
			if(attr.getQName(i).equals("name")) {
				this.composedServiceName = attr.getValue(i);
			}
		}
		printElement(node);
	}

	public void visit(InvokeElement node){
		printElement(node);
		Attributes2Impl attr = node.getAttribues();
		Object obj = null;
		for(int i=0; i<attr.getLength(); i++) {
			if(attr.getQName(i).equals("interface")) {
				obj = RSELRepository.getServiceObject(attr.getValue(i));
			} else if(attr.getQName(i).equals("operation")) {
				if(obj != null) {
					Method[] m = obj.getClass().getMethods();
					for(int j=0; j<m.length; j++) {
						String[] splitedMethodName = m[j].toString().split("[.]");
						String methodName = splitedMethodName[splitedMethodName.length-1];
						if(attr.getValue(i).equals(methodName)) {
							try {
								Object returnValue = null;
								if(methodName.equals("moveForward(int)")) {
									if(count == 0) {
										returnValue = m[j].invoke(obj, 19);
										count++;
									} else {
										returnValue = m[j].invoke(obj, 54);
									}
								} else {
									returnValue = m[j].invoke(obj);
								}
								System.out.println("[SOMAR Server] " + methodName + " is called. Return Value is [ " + returnValue.toString() + " ]");
							} catch (IllegalArgumentException e) {
								e.printStackTrace();
							} catch (IllegalAccessException e) {
								e.printStackTrace();
							} catch (InvocationTargetException e) {
								e.printStackTrace();
							}
						}
					}
				}
			}
//			System.out.println("[SOMAR Server] in for loop / getQName : " + attr.getQName(i));
//			System.out.println("[SOMAR Server] in for loop / getValue : " + attr.getValue(i));
		}
	}

	public void visit(DocumentationElement node){
		printElement(node);
	}

	public void visit(ToElement node){
		printElement(node);
	}

	public void visit(FromElement node){
		printElement(node);
	}

	public void visit(ParameterElement node){
		printElement(node);
	}

	public void visit(ReturnElement node){
		printElement(node);
	}

	public void visit(VariablesElement node){
		printElement(node);
	}

	public void visit(ImportElement node){
		printElement(node);
	}

	public void visit(AssignElement node){
		printElement(node);
	}

	private void printElement(EntryElement node){
		Attributes2Impl attr = node.getAttribues();
//		System.out.print("\n<" + node.getQName());
		Vector<EntryElement> children;

//		for(int i=0; i<attr.getLength(); i++ ) {
//			System.out.print(" " + attr.getQName(i) + " = \"" + attr.getValue(i) + "\"");
//		}
//
//		System.out.println(">");

		children = node.getChildren();
		for(int i=0; i<children.size(); i++){
			EntryElement eNode = children.get(i);
			eNode.accept(this);
		}
//		System.out.println("</" + node.getQName() + ">");
	}
}